package com.zhuss.core.processor;

import java.util.ArrayList;
import java.util.Date;
import java.util.HashSet;
import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Component;

import com.zhuss.bean.bo.core.auth.AuthBo;
import com.zhuss.bean.bo.core.upload.DownloadBo;
import com.zhuss.bean.unit.core.auth.ListUserMenuTreeVo;
import com.zhuss.bean.vo.core.auth.AuthVo;
import com.zhuss.bean.vo.core.upload.DownloadVo;
import com.zhuss.common.AbstractProcessor;
import com.zhuss.common.Processor;
import com.zhuss.core.db.entity.Resource;
import com.zhuss.db.entity.OpLog;
import com.zhuss.enums.EnumUtil;
import com.zhuss.enums.IsEnum;
import com.zhuss.enums.LogActionEnum;
import com.zhuss.enums.MoudleEnum;
import com.zhuss.enums.SystemEnum;
import com.zhuss.exception.OceanException;
import com.zhuss.util.JsonUtil;
import com.zhuss.util.ListBean;

/**
 * 层级菜单
 * 用户的菜单 processor
 * @Author: zhushanshuo
 * @Date: 2019/12/24 17:55
 */
@Component("authMenuProcessor")
public class AuthMenuProcessor extends AbstractProcessor<AuthVo, AuthBo> implements Processor<AuthVo, AuthBo> {

	
	@Autowired
	@Qualifier("userRoleRead")
	private UserRoleRead userRoleRead;
	
	@Autowired
	@Qualifier("rolePermissionRead")
	private RolePermissionRead rolePermissionRead;
	
	@Autowired
	@Qualifier("permissionResourceRead")
	private PermissionResourceRead permissionResourceRead;
	
	
	@Autowired
	@Qualifier("resourceRead")
	private ResourceRead resourceRead;
	
	@Autowired
	@Qualifier("roleRead")
	private RoleRead roleRead;
	
	@Autowired
	@Qualifier("downloadProcessor")
	private Processor<DownloadVo, DownloadBo> downloadProcessor;
	
    /**
     * 校验
     */
    @Override
    public void check(AuthBo bo) throws OceanException {
    	
    }
    
    /**
     * 操作方法
     * @throws OceanException 
     */
	@Override
	@SuppressWarnings("unchecked")
    public AuthVo process(AuthBo bo) throws OceanException {
		List<ListUserMenuTreeVo> menuList = new ArrayList<>();
		List<ListUserMenuTreeVo> menuTreeList = new ArrayList<>();
    	AuthVo result = new AuthVo();
    	// 查询出当前区域用户的角色
    	List<Long> roleIdList = (List<Long>) userRoleRead.listRoleId(bo.getConcurrentUserId());
    	
    	List<Long> permissionIdList = new ArrayList<Long>();
    	// 查询出当前用户的所有角色所关联的权限
    	if (!roleIdList.isEmpty()) {
    		permissionIdList = (List<Long>) rolePermissionRead.listPermissionId(roleIdList);
    	}
    	
    	List<Long> resourceIdList = new ArrayList<Long>();
    	// 查询出当前用户的所有角色所关联的权限， 然后所关联的所有的菜单
    	if (!permissionIdList.isEmpty()) {
    		resourceIdList = (List<Long>) permissionResourceRead.listResourceId(permissionIdList);
    	}
    	List<Long> resourceIdListSystem = (List<Long>) resourceRead.listMenuIdShow(bo.getConcurrentSystem());
    	resourceIdList.retainAll(resourceIdListSystem);
    	
    	List<Long> resourceIdListPublic = (List<Long>) resourceRead.listMenuPublic(bo.getConcurrentSystem());
    	resourceIdList.addAll(resourceIdListPublic);
    	
    	// 层级菜单
    	Long parent = bo.getParent();
    	parent = parent == null ? EnumUtil.containsSystem(SystemEnum.class, bo.getConcurrentSystem()) : parent;
    	List<Long> resourceIdListLevel = (List<Long>) resourceRead.listMenuIdByParent(bo.getConcurrentSystem(), parent);
    	resourceIdList.retainAll(resourceIdListLevel);
    	
    	fixSame(resourceIdList);
    	List<Resource> resourceListAll = resourceRead.listMenuByParent(bo.getConcurrentSystem(), parent);
    	transferToResult(resourceListAll, menuList, resourceIdList);
    	transferTree(resourceListAll, menuTreeList, resourceIdList, bo.getConcurrentSystem());
    	result.setMenuList(new ArrayList<>());
    	result.setMenuTreeList(menuList);
        return result;
    }
	
	/**
	 * 转换菜单树
	 * @param menuList
	 * @param result
	 * @param resourceIdList 
	 * @param system 
	 * @throws OceanException 
	 */
	private void transferTree(List<Resource> menuList, List<ListUserMenuTreeVo> result, List<Long> resourceIdList, Integer system) throws OceanException {
		/*for (Resource menu : menuList) {
			Long parent = menu.getParent();
			if (parent.longValue() == 0l) {
				continue;
			}
			DetailResourceVo resource = (DetailResourceVo) resourceRead.detail(parent);
			if (system.equals(resource.getSystem()) && resource.getParent().longValue() == 0l) {
				ListUserMenuTreeVo vo = new ListUserMenuTreeVo();
				vo.setIcon(menu.getPic());
				String img = menu.getImg();
				vo.setImgUrl(genUrl(img));
				vo.setMenuId(menu.getResourceId());
				vo.setName(menu.getName());
				vo.setExtName(menu.getExtName());
				vo.setRoute(menu.getUrl());
				vo.setExtRoute(menu.getExtUrl());
				vo.setSort(menu.getSort());
				result.add(vo);
			}
		}
		
		for (ListUserMenuTreeVo vo : result) {
			vo.setChildren(init(menuList, vo));
		}*/
	}
	
	private String genUrl(String img) throws OceanException {
		if (img == null || "".equals(img.trim())) {
			return null;
		}
		DownloadBo downloadBo = new DownloadBo();
		downloadBo.setKey(img);
		DownloadVo downloadVo = downloadProcessor.process(downloadBo);
		return downloadVo.getUrl();
	}

	/**
	 * 递归初始化菜单树
	 * @param menuList
	 * @param vo
	 * @return
	 * @throws OceanException 
	 */
	@SuppressWarnings("unused")
	private List<ListUserMenuTreeVo> init(List<Resource> menuList, ListUserMenuTreeVo vo) throws OceanException {
		ListBean<ListUserMenuTreeVo> listBean = new ListBean<>();
		for (Resource menu : menuList) {
			if (vo.getMenuId().equals(menu.getParent())) {
				ListUserMenuTreeVo item = new ListUserMenuTreeVo();
				item.setIcon(menu.getPic());
				String img = menu.getImg();
				item.setImgUrl(genUrl(img));
				String disImg = menu.getDisImg();
				item.setDisImgUrl(genUrl(disImg));
				item.setMenuId(menu.getResourceId());
				item.setName(menu.getName());
				item.setExtName(menu.getExtName());
				item.setRoute(menu.getUrl());
				item.setExtRoute(menu.getExtUrl());
				item.setTag(menu.getTag());
				item.setSort(menu.getSort());
				item.setChildren(init(menuList, item));
				listBean.build(item);
			}
		}
		return listBean.getList();
	}
    
    private void fixSame(List<Long> resourceIdList) {
		HashSet<Long> set = new HashSet<Long>();
		set.addAll(resourceIdList);
		resourceIdList.clear();
		resourceIdList.addAll(set);
		
	}

	private void transferToResult(List<Resource> resourceList,
			List<ListUserMenuTreeVo> result, List<Long> resourceIdList) throws OceanException {
		for (Resource menu : resourceList) {
			ListUserMenuTreeVo vo = new ListUserMenuTreeVo();
			vo.setIcon(menu.getPic());
			String img = menu.getImg();
			vo.setImgUrl(genUrl(img));
			String disImg = menu.getDisImg();
			vo.setDisImgUrl(genUrl(disImg));
			vo.setMenuId(menu.getResourceId());
			vo.setName(menu.getName());
			vo.setExtName(menu.getExtName());
			vo.setRoute(menu.getUrl());
			vo.setExtRoute(menu.getExtUrl());
			vo.setTag(menu.getTag());
			vo.setSort(menu.getSort());
			
			if (resourceIdList.contains(vo.getMenuId())) {
				vo.setIsDis(IsEnum.否.key());
			}
			
			result.add(vo);
		}
	}

	/**
     * 操作日志
     */
	@Override
	public AuthVo log(AuthBo param) throws OceanException {
		OpLog record = new OpLog();
    	record.setMoudle(MoudleEnum.基础模块.key());
    	record.setAction(LogActionEnum.用户的权限.key());
    	record.setTargetId(param.getConcurrentUserId());
    	record.setTargetName(param.getConcurrentUserName());
    	record.setContent("参数: " + JsonUtil.toJson(param));
    	record.setReason(param.getExceptionReason());
    	
    	record.setCreatorId(param.getConcurrentUserId());
    	record.setCreator(param.getConcurrentUserName());
    	record.setCreateTime(new Date());
    	log(record);
    	return null;
	}
}
